using CodePlex.DnD4eCampaignManager.CampaignManagerTests.TestUtilities;
using CodePlex.DnD4eCampaignManager.DnD4e;
using CodePlex.DnD4eCampaignManager.DnD4e.Enums;
using CodePlex.DnD4eCampaignManager.DnD4e.Interfaces;
using NUnit.Framework;
using Rhino.Mocks;
using StructureMap.AutoMocking;

namespace CodePlex.DnD4eCampaignManager.CampaignManagerTests.DnD4eTests
{
    [TestFixture]
    public class MonsterTests
    {
        private RhinoAutoMocker<Monster> _monsterMocker;

        [Test]
        public void AbilitiesComponentHandlesAbilityCharisma()
        {
            const int charisma = 15;
            _monsterMocker.Get<IAbilities>().Expect(x => x.AbilityCharisma).Return(charisma);
            _monsterMocker.Get<IAbilities>().Expect(x => x.AbilityCharisma = charisma);
            _monsterMocker.ClassUnderTest.AbilityCharisma = _monsterMocker.ClassUnderTest.AbilityCharisma;
        }

        [Test]
        public void AbilitiesComponentHandlesAbilityConstitution()
        {
            const int constitution = 15;
            _monsterMocker.Get<IAbilities>().Expect(x => x.AbilityConstitution).Return(constitution);
            _monsterMocker.Get<IAbilities>().Expect(x => x.AbilityConstitution = constitution);
            _monsterMocker.ClassUnderTest.AbilityConstitution = _monsterMocker.ClassUnderTest.AbilityConstitution;
        }

        [Test]
        public void AbilitiesComponentHandlesAbilityDexterity()
        {
            const int dexterity = 15;
            _monsterMocker.Get<IAbilities>().Expect(x => x.AbilityDexterity).Return(dexterity);
            _monsterMocker.Get<IAbilities>().Expect(x => x.AbilityDexterity = dexterity);
            _monsterMocker.ClassUnderTest.AbilityDexterity = _monsterMocker.ClassUnderTest.AbilityDexterity;
        }

        [Test]
        public void AbilitiesComponentHandlesAbilityIntelligence()
        {
            const int intelligence = 15;
            _monsterMocker.Get<IAbilities>().Expect(x => x.AbilityIntelligence).Return(intelligence);
            _monsterMocker.Get<IAbilities>().Expect(x => x.AbilityIntelligence = intelligence);
            _monsterMocker.ClassUnderTest.AbilityIntelligence = _monsterMocker.ClassUnderTest.AbilityIntelligence;
        }

        [Test]
        public void AbilitiesComponentHandlesAbilityStrength()
        {
            const int strength = 15;
            _monsterMocker.Get<IAbilities>().Expect(x => x.AbilityStrength).Return(strength);
            _monsterMocker.Get<IAbilities>().Expect(x => x.AbilityStrength = strength);
            _monsterMocker.ClassUnderTest.AbilityStrength = _monsterMocker.ClassUnderTest.AbilityStrength;
        }

        [Test]
        public void AbilitiesComponentHandlesAbilityWisdom()
        {
            const int wisdom = 15;
            _monsterMocker.Get<IAbilities>().Expect(x => x.AbilityWisdom).Return(wisdom);
            _monsterMocker.Get<IAbilities>().Expect(x => x.AbilityWisdom = wisdom);
            _monsterMocker.ClassUnderTest.AbilityWisdom = _monsterMocker.ClassUnderTest.AbilityWisdom;
        }

        [Test]
        public void CalculateExperiencePointValueIsCorrect()
        {
            const bool elite = false;
            const bool solo = false;
            const MonsterRole role = MonsterRole.Brute;
            Assert.AreEqual(100, Monster.CalculateExperiencePointValue(1, elite, solo, role));
            Assert.AreEqual(125, Monster.CalculateExperiencePointValue(2, elite, solo, role));
            Assert.AreEqual(150, Monster.CalculateExperiencePointValue(3, elite, solo, role));
            Assert.AreEqual(175, Monster.CalculateExperiencePointValue(4, elite, solo, role));
            Assert.AreEqual(200, Monster.CalculateExperiencePointValue(5, elite, solo, role));
            Assert.AreEqual(250, Monster.CalculateExperiencePointValue(6, elite, solo, role));
            Assert.AreEqual(300, Monster.CalculateExperiencePointValue(7, elite, solo, role));
            Assert.AreEqual(350, Monster.CalculateExperiencePointValue(8, elite, solo, role));
            Assert.AreEqual(400, Monster.CalculateExperiencePointValue(9, elite, solo, role));
            Assert.AreEqual(500, Monster.CalculateExperiencePointValue(10, elite, solo, role));
            Assert.AreEqual(600, Monster.CalculateExperiencePointValue(11, elite, solo, role));
            Assert.AreEqual(700, Monster.CalculateExperiencePointValue(12, elite, solo, role));
            Assert.AreEqual(800, Monster.CalculateExperiencePointValue(13, elite, solo, role));
            Assert.AreEqual(1000, Monster.CalculateExperiencePointValue(14, elite, solo, role));
            Assert.AreEqual(1200, Monster.CalculateExperiencePointValue(15, elite, solo, role));
            Assert.AreEqual(1400, Monster.CalculateExperiencePointValue(16, elite, solo, role));
            Assert.AreEqual(1600, Monster.CalculateExperiencePointValue(17, elite, solo, role));
            Assert.AreEqual(2000, Monster.CalculateExperiencePointValue(18, elite, solo, role));
            Assert.AreEqual(2400, Monster.CalculateExperiencePointValue(19, elite, solo, role));
            Assert.AreEqual(2800, Monster.CalculateExperiencePointValue(20, elite, solo, role));
            Assert.AreEqual(3200, Monster.CalculateExperiencePointValue(21, elite, solo, role));
            Assert.AreEqual(4150, Monster.CalculateExperiencePointValue(22, elite, solo, role));
            Assert.AreEqual(5100, Monster.CalculateExperiencePointValue(23, elite, solo, role));
            Assert.AreEqual(6050, Monster.CalculateExperiencePointValue(24, elite, solo, role));
            Assert.AreEqual(7000, Monster.CalculateExperiencePointValue(25, elite, solo, role));
            Assert.AreEqual(9000, Monster.CalculateExperiencePointValue(26, elite, solo, role));
            Assert.AreEqual(11000, Monster.CalculateExperiencePointValue(27, elite, solo, role));
            Assert.AreEqual(13000, Monster.CalculateExperiencePointValue(28, elite, solo, role));
            Assert.AreEqual(15000, Monster.CalculateExperiencePointValue(29, elite, solo, role));
            Assert.AreEqual(19000, Monster.CalculateExperiencePointValue(30, elite, solo, role));
            Assert.AreEqual(23000, Monster.CalculateExperiencePointValue(31, elite, solo, role));
            Assert.AreEqual(27000, Monster.CalculateExperiencePointValue(32, elite, solo, role));
            Assert.AreEqual(31000, Monster.CalculateExperiencePointValue(33, elite, solo, role));
            Assert.AreEqual(39000, Monster.CalculateExperiencePointValue(34, elite, solo, role));
            Assert.AreEqual(47000, Monster.CalculateExperiencePointValue(35, elite, solo, role));
            Assert.AreEqual(55000, Monster.CalculateExperiencePointValue(36, elite, solo, role));
            Assert.AreEqual(63000, Monster.CalculateExperiencePointValue(37, elite, solo, role));
            Assert.AreEqual(79000, Monster.CalculateExperiencePointValue(38, elite, solo, role));
            Assert.AreEqual(95000, Monster.CalculateExperiencePointValue(39, elite, solo, role));
            Assert.AreEqual(111000, Monster.CalculateExperiencePointValue(40, elite, solo, role));
        }

        [Test]
        public void CalculateExperiencePointValueIsCorrectForElite()
        {
            const bool elite = true;
            const bool solo = false;
            const MonsterRole role = MonsterRole.Brute;
            Assert.AreEqual(200, Monster.CalculateExperiencePointValue(1, elite, solo, role));
            Assert.AreEqual(250, Monster.CalculateExperiencePointValue(2, elite, solo, role));
            Assert.AreEqual(300, Monster.CalculateExperiencePointValue(3, elite, solo, role));
            Assert.AreEqual(350, Monster.CalculateExperiencePointValue(4, elite, solo, role));
            Assert.AreEqual(400, Monster.CalculateExperiencePointValue(5, elite, solo, role));
            Assert.AreEqual(500, Monster.CalculateExperiencePointValue(6, elite, solo, role));
            Assert.AreEqual(600, Monster.CalculateExperiencePointValue(7, elite, solo, role));
            Assert.AreEqual(700, Monster.CalculateExperiencePointValue(8, elite, solo, role));
            Assert.AreEqual(800, Monster.CalculateExperiencePointValue(9, elite, solo, role));
            Assert.AreEqual(1000, Monster.CalculateExperiencePointValue(10, elite, solo, role));
            Assert.AreEqual(1200, Monster.CalculateExperiencePointValue(11, elite, solo, role));
            Assert.AreEqual(1400, Monster.CalculateExperiencePointValue(12, elite, solo, role));
            Assert.AreEqual(1600, Monster.CalculateExperiencePointValue(13, elite, solo, role));
            Assert.AreEqual(2000, Monster.CalculateExperiencePointValue(14, elite, solo, role));
            Assert.AreEqual(2400, Monster.CalculateExperiencePointValue(15, elite, solo, role));
            Assert.AreEqual(2800, Monster.CalculateExperiencePointValue(16, elite, solo, role));
            Assert.AreEqual(3200, Monster.CalculateExperiencePointValue(17, elite, solo, role));
            Assert.AreEqual(4000, Monster.CalculateExperiencePointValue(18, elite, solo, role));
            Assert.AreEqual(4800, Monster.CalculateExperiencePointValue(19, elite, solo, role));
            Assert.AreEqual(5600, Monster.CalculateExperiencePointValue(20, elite, solo, role));
            Assert.AreEqual(6400, Monster.CalculateExperiencePointValue(21, elite, solo, role));
            Assert.AreEqual(8300, Monster.CalculateExperiencePointValue(22, elite, solo, role));
            Assert.AreEqual(10200, Monster.CalculateExperiencePointValue(23, elite, solo, role));
            Assert.AreEqual(12100, Monster.CalculateExperiencePointValue(24, elite, solo, role));
            Assert.AreEqual(14000, Monster.CalculateExperiencePointValue(25, elite, solo, role));
            Assert.AreEqual(18000, Monster.CalculateExperiencePointValue(26, elite, solo, role));
            Assert.AreEqual(22000, Monster.CalculateExperiencePointValue(27, elite, solo, role));
            Assert.AreEqual(26000, Monster.CalculateExperiencePointValue(28, elite, solo, role));
            Assert.AreEqual(30000, Monster.CalculateExperiencePointValue(29, elite, solo, role));
            Assert.AreEqual(38000, Monster.CalculateExperiencePointValue(30, elite, solo, role));
            Assert.AreEqual(46000, Monster.CalculateExperiencePointValue(31, elite, solo, role));
            Assert.AreEqual(54000, Monster.CalculateExperiencePointValue(32, elite, solo, role));
            Assert.AreEqual(62000, Monster.CalculateExperiencePointValue(33, elite, solo, role));
            Assert.AreEqual(78000, Monster.CalculateExperiencePointValue(34, elite, solo, role));
            Assert.AreEqual(94000, Monster.CalculateExperiencePointValue(35, elite, solo, role));
            Assert.AreEqual(110000, Monster.CalculateExperiencePointValue(36, elite, solo, role));
            Assert.AreEqual(126000, Monster.CalculateExperiencePointValue(37, elite, solo, role));
            Assert.AreEqual(158000, Monster.CalculateExperiencePointValue(38, elite, solo, role));
            Assert.AreEqual(190000, Monster.CalculateExperiencePointValue(39, elite, solo, role));
            Assert.AreEqual(222000, Monster.CalculateExperiencePointValue(40, elite, solo, role));
        }

        [Test]
        public void CalculateExperiencePointValueIsCorrectForMinion()
        {
            const bool elite = false;
            const bool solo = false;
            const MonsterRole role = MonsterRole.Minion;
            Assert.AreEqual(25, Monster.CalculateExperiencePointValue(1, elite, solo, role));
            Assert.AreEqual(31, Monster.CalculateExperiencePointValue(2, elite, solo, role));
            Assert.AreEqual(38, Monster.CalculateExperiencePointValue(3, elite, solo, role));
            Assert.AreEqual(44, Monster.CalculateExperiencePointValue(4, elite, solo, role));
            Assert.AreEqual(50, Monster.CalculateExperiencePointValue(5, elite, solo, role));
            Assert.AreEqual(63, Monster.CalculateExperiencePointValue(6, elite, solo, role));
            Assert.AreEqual(75, Monster.CalculateExperiencePointValue(7, elite, solo, role));
            Assert.AreEqual(88, Monster.CalculateExperiencePointValue(8, elite, solo, role));
            Assert.AreEqual(100, Monster.CalculateExperiencePointValue(9, elite, solo, role));
            Assert.AreEqual(125, Monster.CalculateExperiencePointValue(10, elite, solo, role));
            Assert.AreEqual(150, Monster.CalculateExperiencePointValue(11, elite, solo, role));
            Assert.AreEqual(175, Monster.CalculateExperiencePointValue(12, elite, solo, role));
            Assert.AreEqual(200, Monster.CalculateExperiencePointValue(13, elite, solo, role));
            Assert.AreEqual(250, Monster.CalculateExperiencePointValue(14, elite, solo, role));
            Assert.AreEqual(300, Monster.CalculateExperiencePointValue(15, elite, solo, role));
            Assert.AreEqual(350, Monster.CalculateExperiencePointValue(16, elite, solo, role));
            Assert.AreEqual(400, Monster.CalculateExperiencePointValue(17, elite, solo, role));
            Assert.AreEqual(500, Monster.CalculateExperiencePointValue(18, elite, solo, role));
            Assert.AreEqual(600, Monster.CalculateExperiencePointValue(19, elite, solo, role));
            Assert.AreEqual(700, Monster.CalculateExperiencePointValue(20, elite, solo, role));
            Assert.AreEqual(800, Monster.CalculateExperiencePointValue(21, elite, solo, role));
            Assert.AreEqual(1038, Monster.CalculateExperiencePointValue(22, elite, solo, role));
            Assert.AreEqual(1275, Monster.CalculateExperiencePointValue(23, elite, solo, role));
            Assert.AreEqual(1513, Monster.CalculateExperiencePointValue(24, elite, solo, role));
            Assert.AreEqual(1750, Monster.CalculateExperiencePointValue(25, elite, solo, role));
            Assert.AreEqual(2250, Monster.CalculateExperiencePointValue(26, elite, solo, role));
            Assert.AreEqual(2750, Monster.CalculateExperiencePointValue(27, elite, solo, role));
            Assert.AreEqual(3250, Monster.CalculateExperiencePointValue(28, elite, solo, role));
            Assert.AreEqual(3750, Monster.CalculateExperiencePointValue(29, elite, solo, role));
            Assert.AreEqual(4750, Monster.CalculateExperiencePointValue(30, elite, solo, role));
            Assert.AreEqual(5750, Monster.CalculateExperiencePointValue(31, elite, solo, role));
            Assert.AreEqual(6750, Monster.CalculateExperiencePointValue(32, elite, solo, role));
            Assert.AreEqual(7750, Monster.CalculateExperiencePointValue(33, elite, solo, role));
            Assert.AreEqual(9750, Monster.CalculateExperiencePointValue(34, elite, solo, role));
            Assert.AreEqual(11750, Monster.CalculateExperiencePointValue(35, elite, solo, role));
            Assert.AreEqual(13750, Monster.CalculateExperiencePointValue(36, elite, solo, role));
            Assert.AreEqual(15750, Monster.CalculateExperiencePointValue(37, elite, solo, role));
            Assert.AreEqual(19750, Monster.CalculateExperiencePointValue(38, elite, solo, role));
            Assert.AreEqual(23750, Monster.CalculateExperiencePointValue(39, elite, solo, role));
            Assert.AreEqual(27750, Monster.CalculateExperiencePointValue(40, elite, solo, role));
        }

        [Test]
        public void CalculateExperiencePointValueIsCorrectForSolo()
        {
            const bool elite = false;
            const bool solo = true;
            const MonsterRole role = MonsterRole.Brute;
            Assert.AreEqual(500, Monster.CalculateExperiencePointValue(1, elite, solo, role));
            Assert.AreEqual(625, Monster.CalculateExperiencePointValue(2, elite, solo, role));
            Assert.AreEqual(750, Monster.CalculateExperiencePointValue(3, elite, solo, role));
            Assert.AreEqual(875, Monster.CalculateExperiencePointValue(4, elite, solo, role));
            Assert.AreEqual(1000, Monster.CalculateExperiencePointValue(5, elite, solo, role));
            Assert.AreEqual(1250, Monster.CalculateExperiencePointValue(6, elite, solo, role));
            Assert.AreEqual(1500, Monster.CalculateExperiencePointValue(7, elite, solo, role));
            Assert.AreEqual(1750, Monster.CalculateExperiencePointValue(8, elite, solo, role));
            Assert.AreEqual(2000, Monster.CalculateExperiencePointValue(9, elite, solo, role));
            Assert.AreEqual(2500, Monster.CalculateExperiencePointValue(10, elite, solo, role));
            Assert.AreEqual(3000, Monster.CalculateExperiencePointValue(11, elite, solo, role));
            Assert.AreEqual(3500, Monster.CalculateExperiencePointValue(12, elite, solo, role));
            Assert.AreEqual(4000, Monster.CalculateExperiencePointValue(13, elite, solo, role));
            Assert.AreEqual(5000, Monster.CalculateExperiencePointValue(14, elite, solo, role));
            Assert.AreEqual(6000, Monster.CalculateExperiencePointValue(15, elite, solo, role));
            Assert.AreEqual(7000, Monster.CalculateExperiencePointValue(16, elite, solo, role));
            Assert.AreEqual(8000, Monster.CalculateExperiencePointValue(17, elite, solo, role));
            Assert.AreEqual(10000, Monster.CalculateExperiencePointValue(18, elite, solo, role));
            Assert.AreEqual(12000, Monster.CalculateExperiencePointValue(19, elite, solo, role));
            Assert.AreEqual(14000, Monster.CalculateExperiencePointValue(20, elite, solo, role));
            Assert.AreEqual(16000, Monster.CalculateExperiencePointValue(21, elite, solo, role));
            Assert.AreEqual(20750, Monster.CalculateExperiencePointValue(22, elite, solo, role));
            Assert.AreEqual(25500, Monster.CalculateExperiencePointValue(23, elite, solo, role));
            Assert.AreEqual(30250, Monster.CalculateExperiencePointValue(24, elite, solo, role));
            Assert.AreEqual(35000, Monster.CalculateExperiencePointValue(25, elite, solo, role));
            Assert.AreEqual(45000, Monster.CalculateExperiencePointValue(26, elite, solo, role));
            Assert.AreEqual(55000, Monster.CalculateExperiencePointValue(27, elite, solo, role));
            Assert.AreEqual(65000, Monster.CalculateExperiencePointValue(28, elite, solo, role));
            Assert.AreEqual(75000, Monster.CalculateExperiencePointValue(29, elite, solo, role));
            Assert.AreEqual(95000, Monster.CalculateExperiencePointValue(30, elite, solo, role));
            Assert.AreEqual(115000, Monster.CalculateExperiencePointValue(31, elite, solo, role));
            Assert.AreEqual(135000, Monster.CalculateExperiencePointValue(32, elite, solo, role));
            Assert.AreEqual(155000, Monster.CalculateExperiencePointValue(33, elite, solo, role));
            Assert.AreEqual(195000, Monster.CalculateExperiencePointValue(34, elite, solo, role));
            Assert.AreEqual(235000, Monster.CalculateExperiencePointValue(35, elite, solo, role));
            Assert.AreEqual(275000, Monster.CalculateExperiencePointValue(36, elite, solo, role));
            Assert.AreEqual(315000, Monster.CalculateExperiencePointValue(37, elite, solo, role));
            Assert.AreEqual(395000, Monster.CalculateExperiencePointValue(38, elite, solo, role));
            Assert.AreEqual(475000, Monster.CalculateExperiencePointValue(39, elite, solo, role));
            Assert.AreEqual(555000, Monster.CalculateExperiencePointValue(40, elite, solo, role));
        }

        [Test]
        public void CombatantIsFormatedProperlyForDisplay()
        {
            IMonster combatant1 = DefaultTestObjects.TestMonster();
            IMonster combatant2 = DefaultTestObjects.TestMonster();
            combatant2.Index = 3;
            Assert.AreEqual("Goblin Warrior - 40 (11 temp)/60; AC: 15, Fort: 14, Ref: 17, Will: 20; Speed: 6, Climb 4",
                            combatant1.FormatCombatantForDisplay());
            Assert.AreEqual("Goblin Warrior 3 - 40 (11 temp)/60; AC: 15, Fort: 14, Ref: 17, Will: 20; Speed: 6, Climb 4",
                            combatant2.FormatCombatantForDisplay());
        }

        [Test]
        public void DefensesComponentHandlesDefenseArmorClass()
        {
            const int armorClass = 12;
            _monsterMocker.Get<IDefenses>().Expect(x => x.DefenseArmorClass = armorClass);
            _monsterMocker.Get<IDefenses>().Expect(x => x.DefenseArmorClass).Return(armorClass);
            _monsterMocker.ClassUnderTest.DefenseArmorClass = _monsterMocker.ClassUnderTest.DefenseArmorClass;
        }

        [Test]
        public void DefensesComponentHandlesDefenseFortitude()
        {
            const int fortitudeDefense = 12;
            _monsterMocker.Get<IDefenses>().Expect(x => x.DefenseFortitude = fortitudeDefense);
            _monsterMocker.Get<IDefenses>().Expect(x => x.DefenseFortitude).Return(fortitudeDefense);
            _monsterMocker.ClassUnderTest.DefenseFortitude = _monsterMocker.ClassUnderTest.DefenseFortitude;
        }

        [Test]
        public void DefensesComponentHandlesDefenseReflex()
        {
            const int reflexDefense = 12;
            _monsterMocker.Get<IDefenses>().Expect(x => x.DefenseReflex = reflexDefense);
            _monsterMocker.Get<IDefenses>().Expect(x => x.DefenseReflex).Return(reflexDefense);
            _monsterMocker.ClassUnderTest.DefenseReflex = _monsterMocker.ClassUnderTest.DefenseReflex;
        }

        [Test]
        public void DefensesComponentHandlesDefenseWillpower()
        {
            const int willpowerDefense = 12;
            _monsterMocker.Get<IDefenses>().Expect(x => x.DefenseWillpower = willpowerDefense);
            _monsterMocker.Get<IDefenses>().Expect(x => x.DefenseWillpower).Return(willpowerDefense);
            _monsterMocker.ClassUnderTest.DefenseWillpower = _monsterMocker.ClassUnderTest.DefenseWillpower;
        }

        [Test]
        public void DisplayNameIncludesIndex()
        {
            const string name = "Your Mom";
            const int index = 3;
            _monsterMocker.ClassUnderTest.Name = name;
            Assert.AreEqual(name, _monsterMocker.ClassUnderTest.DisplayName);
            _monsterMocker.ClassUnderTest.Index = index;
            Assert.AreEqual(string.Format("{0} {1}", name, index), _monsterMocker.ClassUnderTest.DisplayName);
        }

        [Test]
        public void HasAtWillPowers()
        {
            const string attackPowers = "Melee - Spear (standard; at-will) - +6 vs. AC; 1d8 + 2 damage.";
            _monsterMocker.ClassUnderTest.AttackPowers = attackPowers;
            Assert.AreEqual(attackPowers, _monsterMocker.ClassUnderTest.AttackPowers);
        }

        [Test]
        public void HasConditions()
        {
            const string conditions = "5 Ongoing Fire Damage (Save Ends)";
            _monsterMocker.ClassUnderTest.Conditions = conditions;
            Assert.AreEqual(conditions, _monsterMocker.ClassUnderTest.Conditions);
        }

        [Test]
        public void HasName()
        {
            const string name = "D. Baggerton";
            _monsterMocker.ClassUnderTest.Name = name;
            Assert.AreEqual(name, _monsterMocker.ClassUnderTest.Name);
        }

        [Test]
        public void HasOptionalIndexNumberToSupportMultipleInstancesOfTheSameCreatureInOneCombatEncounter()
        {
            const int index = 3;
            _monsterMocker.ClassUnderTest.Index = index;
            Assert.AreEqual(index, _monsterMocker.ClassUnderTest.Index.GetValueOrDefault());
        }

        [Test]
        public void HasSpecialQualities()
        {
            const string specialQualities = "Resist Cold 5";
            _monsterMocker.ClassUnderTest.SpecialQualities = specialQualities;
            Assert.AreEqual(specialQualities, _monsterMocker.ClassUnderTest.SpecialQualities);
        }

        [Test]
        public void HasTactics()
        {
            const string tactics = "Action Points = 1";
            _monsterMocker.ClassUnderTest.Tactics = tactics;
            Assert.AreEqual(tactics, _monsterMocker.ClassUnderTest.Tactics);
        }

        [Test]
        public void HitPointComponentHandlesHealing()
        {
            const int hitPointsRecovered = 5;
            _monsterMocker.Get<IHitPoints>().Expect(x => x.Heal(hitPointsRecovered));
            _monsterMocker.ClassUnderTest.Heal(hitPointsRecovered);
        }

        [Test]
        public void HitPointComponentHandlesHitPointsBloodied()
        {
            const int hitPointsBloodied = 5;
            _monsterMocker.Get<IHitPoints>().Expect(x => x.HitPointsBloodied).Return(hitPointsBloodied);
            Assert.AreEqual(hitPointsBloodied, _monsterMocker.ClassUnderTest.HitPointsBloodied);
        }

        [Test]
        public void HitPointComponentHandlesHitPointsCurrent()
        {
            const int hitPointsCurrent = 5;
            _monsterMocker.Get<IHitPoints>().Expect(x => x.HitPointsCurrent = hitPointsCurrent);
            _monsterMocker.Get<IHitPoints>().Expect(x => x.HitPointsCurrent).Return(hitPointsCurrent);
            _monsterMocker.ClassUnderTest.HitPointsCurrent = _monsterMocker.ClassUnderTest.HitPointsCurrent;
        }

        [Test]
        public void HitPointComponentHandlesHitPointsMaximim()
        {
            const int hitPointsMaximum = 5;
            _monsterMocker.Get<IHitPoints>().Expect(x => x.HitPointsMaximum = hitPointsMaximum);
            _monsterMocker.Get<IHitPoints>().Expect(x => x.HitPointsMaximum).Return(hitPointsMaximum);
            _monsterMocker.ClassUnderTest.HitPointsMaximum = _monsterMocker.ClassUnderTest.HitPointsMaximum;
        }

        [Test]
        public void HitPointComponentHandlesHitPointsTemporary()
        {
            const int hitPointsTemporary = 5;
            _monsterMocker.Get<IHitPoints>().Expect(x => x.HitPointsTemporary = hitPointsTemporary);
            _monsterMocker.Get<IHitPoints>().Expect(x => x.HitPointsTemporary).Return(hitPointsTemporary);
            _monsterMocker.ClassUnderTest.HitPointsTemporary = _monsterMocker.ClassUnderTest.HitPointsTemporary;
        }

        [Test]
        public void HitPointComponentHandlesIsBloodied()
        {
            _monsterMocker.Get<IHitPoints>().Expect(x => x.IsBloodied).Return(true);
            Assert.IsTrue(_monsterMocker.ClassUnderTest.IsBloodied);
        }

        [Test]
        public void HitPointsComponentHandlesDamage()
        {
            const int hitPointsLost = 5;
            _monsterMocker.Get<IHitPoints>().Expect(x => x.Damage(hitPointsLost));
            _monsterMocker.ClassUnderTest.Damage(hitPointsLost);
        }

        [Test]
        public void ImplementsIAbilities()
        {
            Assert.IsInstanceOfType(typeof ( IAbilities ), _monsterMocker.ClassUnderTest);
        }

        [Test]
        public void ImplementsICombatant()
        {
            Assert.IsInstanceOfType(typeof ( ICombatant ), _monsterMocker.ClassUnderTest);
        }

        [Test]
        public void ImplementsIDefenses()
        {
            Assert.IsInstanceOfType(typeof ( IDefenses ), _monsterMocker.ClassUnderTest);
        }

        [Test]
        public void ImplementsIHitPoints()
        {
            Assert.IsInstanceOfType(typeof ( IHitPoints ), _monsterMocker.ClassUnderTest);
        }

        [Test]
        public void ImplementsIInitiative()
        {
            Assert.IsInstanceOfType(typeof ( IInitiative ), _monsterMocker.ClassUnderTest);
        }

        [Test]
        public void ImplementsIMonster()
        {
            Assert.IsInstanceOfType(typeof ( IMonster ), _monsterMocker.ClassUnderTest);
        }

        [Test]
        public void ImplementsIMovement()
        {
            Assert.IsInstanceOfType(typeof ( IMovement ), _monsterMocker.ClassUnderTest);
        }

        [Test]
        public void ImplementsISenses()
        {
            Assert.IsInstanceOfType(typeof ( ISenses ), _monsterMocker.ClassUnderTest);
        }

        [Test]
        public void InitiativeComponentHandlesIniativeScore()
        {
            const int initiativeScore = 5;
            _monsterMocker.Get<IInitiative>().Expect(x => x.InitiativeScore).Return(initiativeScore);
            _monsterMocker.Get<IInitiative>().Expect(x => x.InitiativeScore = initiativeScore);
            _monsterMocker.ClassUnderTest.InitiativeScore = _monsterMocker.ClassUnderTest.InitiativeScore;
        }

        [Test]
        public void InitiativeComponentHandlesInitiativeModifier()
        {
            const int initiativeModifier = 6;
            _monsterMocker.Get<IInitiative>().Expect(x => x.InitiativeModifier).Return(initiativeModifier);
            _monsterMocker.Get<IInitiative>().Expect(x => x.InitiativeModifier = initiativeModifier);
            _monsterMocker.ClassUnderTest.InitiativeModifier = _monsterMocker.ClassUnderTest.InitiativeModifier;
        }

        [Test]
        public void InitiativeComponentHandlesInitiativeRoll()
        {
            const int initiativeRoll = 7;
            _monsterMocker.Get<IInitiative>().Expect(x => x.InitiativeRoll).Return(initiativeRoll);
            _monsterMocker.Get<IInitiative>().Expect(x => x.InitiativeRoll = initiativeRoll);
            _monsterMocker.ClassUnderTest.InitiativeRoll = _monsterMocker.ClassUnderTest.InitiativeRoll;
        }

        [Test]
        public void IsEquatable()
        {
            Monster primaryDomainObject = new Monster(new Abilities(), new Defenses(), new HitPoints(), new Movement(), new Senses(), new Initiative()) { Name = "Goblin", Index = 1 };
            Monster duplicateDomainObject = new Monster(new Abilities(), new Defenses(), new HitPoints(), new Movement(), new Senses(), new Initiative()) { Name = "Goblin", Index = 1 };
            Monster differentDomainObject = new Monster(new Abilities(), new Defenses(), new HitPoints(), new Movement(), new Senses(), new Initiative()) { Name = "Orge", Index = 3 };

            TestHelpers.TestEquatabilityExcludingOperators(primaryDomainObject, duplicateDomainObject, differentDomainObject);
            Assert.IsTrue(primaryDomainObject == duplicateDomainObject);
            Assert.IsTrue(primaryDomainObject != differentDomainObject);
        }

        [Test]
        public void MovementComponentHandlesMovementSpeed()
        {
            const int alternateMovementModes = 8;
            _monsterMocker.Get<IMovement>().Expect(x => x.MovementSpeed = alternateMovementModes);
            _monsterMocker.Get<IMovement>().Expect(x => x.MovementSpeed).Return(alternateMovementModes);
            _monsterMocker.ClassUnderTest.MovementSpeed = _monsterMocker.ClassUnderTest.MovementSpeed;
        }

        [Test]
        public void MovementComponentHandlesMovementSpeedOther()
        {
            const string alternateMovementModes = "Swim 10";
            _monsterMocker.Get<IMovement>().Expect(x => x.MovementSpeedOther = alternateMovementModes);
            _monsterMocker.Get<IMovement>().Expect(x => x.MovementSpeedOther).Return(alternateMovementModes);
            _monsterMocker.ClassUnderTest.MovementSpeedOther = _monsterMocker.ClassUnderTest.MovementSpeedOther;
        }

        [Test]
        public void MovementComponentHandlesMovementStealth()
        {
            const int movementStealth = 8;
            _monsterMocker.Get<IMovement>().Expect(x => x.MovementStealth = movementStealth);
            _monsterMocker.Get<IMovement>().Expect(x => x.MovementStealth).Return(movementStealth);
            _monsterMocker.ClassUnderTest.MovementStealth = _monsterMocker.ClassUnderTest.MovementStealth;
        }

        [Test]
        public void SensesComponentHandlesInsight()
        {
            const int insight = 12;
            _monsterMocker.Get<ISenses>().Expect(x => x.SensesInsight = insight);
            _monsterMocker.Get<ISenses>().Expect(x => x.SensesInsight).Return(insight);
            _monsterMocker.ClassUnderTest.SensesInsight = _monsterMocker.ClassUnderTest.SensesInsight;
        }

        [Test]
        public void SensesComponentHandlesInsightPassive()
        {
            const int insightPassive = 12;
            _monsterMocker.Get<ISenses>().Expect(x => x.SensesInsightPassive = insightPassive);
            _monsterMocker.Get<ISenses>().Expect(x => x.SensesInsightPassive).Return(insightPassive);
            _monsterMocker.ClassUnderTest.SensesInsightPassive = _monsterMocker.ClassUnderTest.SensesInsightPassive;
        }

        [Test]
        public void SensesComponentHandlesPerception()
        {
            const int perception = 12;
            _monsterMocker.Get<ISenses>().Expect(x => x.SensesPerception = perception);
            _monsterMocker.Get<ISenses>().Expect(x => x.SensesPerception).Return(perception);
            _monsterMocker.ClassUnderTest.SensesPerception = _monsterMocker.ClassUnderTest.SensesPerception;
        }

        [Test]
        public void SensesComponentHandlesPerceptionPassive()
        {
            const int perception = 12;
            _monsterMocker.Get<ISenses>().Expect(x => x.SensesPerceptionPassive = perception);
            _monsterMocker.Get<ISenses>().Expect(x => x.SensesPerceptionPassive).Return(perception);
            _monsterMocker.ClassUnderTest.SensesPerceptionPassive = _monsterMocker.ClassUnderTest.SensesPerceptionPassive;
        }

        [Test]
        public void SensesComponentHandlesSensesOther()
        {
            const string sensesOther = "dark vision";
            _monsterMocker.Get<ISenses>().Expect(x => x.SensesOther = sensesOther);
            _monsterMocker.Get<ISenses>().Expect(x => x.SensesOther).Return(sensesOther);
            _monsterMocker.ClassUnderTest.SensesOther = _monsterMocker.ClassUnderTest.SensesOther;
        }

        [SetUp]
        public void SetUp()
        {
            _monsterMocker = new RhinoAutoMocker<Monster>();
        }

        [TearDown]
        public void TearDown()
        {
            _monsterMocker.Get<IInitiative>().VerifyAllExpectations();
            _monsterMocker.Get<IAbilities>().VerifyAllExpectations();
            _monsterMocker.Get<IHitPoints>().VerifyAllExpectations();
            _monsterMocker.Get<ISenses>().VerifyAllExpectations();
            _monsterMocker.Get<IMovement>().VerifyAllExpectations();
            _monsterMocker.Get<IDefenses>().VerifyAllExpectations();
        }
    }
}